package com.retain.system.shiro.realm;

import com.alibaba.fastjson.JSON;
import com.retain.system.service.UserService;
import com.retain.system.vo.ResourceVO;
import com.retain.system.vo.RoleVO;
import com.retain.system.vo.UserVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;


/**
 * @author: LiuWei
 * @date: Create in 16:12 2018/10/15
 */
@Slf4j
public class MyShiroRealm extends AuthorizingRealm {


    @Autowired
    UserService userService;

    /**
     * 提供用户信息，返回权限信息
     *
     * @param principals
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        log.info("---------------------------->授权认证：");
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        String userName = (String) principals.getPrimaryPrincipal();
        UserVO userVO = userService.findUserByAccount(userName);

        for (RoleVO roleVO : userVO.getRoles()) {
            // 将角色名称组成的Set提供给授权info
            authorizationInfo.addRole(roleVO.getCode());
        }
        for (ResourceVO resourceVO : userVO.getResources()) {
            // 将权限名称组成的Set提供给info
            authorizationInfo.addStringPermission(resourceVO.getUrl());
        }
        return authorizationInfo;
    }

    /**
     * 提供帐户信息，返回认证信息
     *
     * @param authenticationToken
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {

        String userName = (String) authenticationToken.getPrincipal();
        UserVO user = userService.findUserByAccount(userName);
        if (user == null) {
            //用户不存在就抛出异常
            throw new UnknownAccountException();
        }
        log.info("---------------------------->登陆成功:{}", JSON.toJSONString(user, true));

//        if (State.LOCKED.equals(user.getState())) {
//            //用户被锁定就抛异常
//            throw new LockedAccountException();
//        }
        //密码可以通过SimpleHash加密，然后保存进数据库。
        //此处是获取数据库内的账号、密码、盐值，保存到登陆信息info中
        SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(user.getAccount(),
                user.getPassWord(),
//                ByteSource.Util.bytes(user.getAccount() + "123"), //salt=username+salt
                getName());                   //realm name

        return authenticationInfo;
    }
}
